package br.com.fiap.sas.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;

import br.com.fiap.sas.bean.Movimentacao;
import br.com.fiap.sas.factory.ConnectionFactory;

public class MovimentacaoDAO {
	
	public static void incluirMovimentacaoDia(Movimentacao movimentacao) throws SQLException {
		java.sql.Date vencimentoSql;
 		Connection conn = ConnectionFactory.getConnection();
		String campos = "valor, codigo_origem, tipo_movimentacao, descricao, vencimento";
		String valores = "?, ?, ?, ?, ?";
		String sql;

		if(movimentacao.getCodigoDestino() != null) { //TRANSFERENCIA
			campos  += ", codigo_destino, codigo_favorecido";
			valores += ", ?, ?";
		}

		sql = "INSERT INTO movimentacao (" + campos + ") VALUES (" + valores + ")";

		if(movimentacao.getVencimento() == null) {
			vencimentoSql = null;
		} else {
			vencimentoSql = new java.sql.Date(movimentacao.getVencimento().getTime());
		}

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setDouble(1, movimentacao.getValor());
		stmt.setInt(2, movimentacao.getCodigoOrigem());
		stmt.setString(3, movimentacao.getTipoMovimentacao());
		stmt.setString(4, movimentacao.getDescricao());
		stmt.setDate(5, vencimentoSql);
		if(movimentacao.getCodigoDestino() != null) {
			stmt.setInt(6, movimentacao.getCodigoDestino());
			stmt.setInt(7, movimentacao.getCodigoFavorecido());	
		}
		stmt.executeUpdate();
		conn.close();
 	}
	
	public static void incluirMovimentacaoAgendamento(Movimentacao movimentacao) throws SQLException {
		java.sql.Date dataSql;
		java.sql.Date vencimentoSql;
 		Connection conn = ConnectionFactory.getConnection();
		String campos = "valor, codigo_origem, tipo_movimentacao, descricao, data_hora_efetivacao, vencimento";
		String valores = "?, ?, ?, ?, ?, ?";
		String sql;

		if(movimentacao.getCodigoDestino() != null) { //TRANSFERENCIA
			campos  += ", codigo_destino, codigo_favorecido";
			valores += ", ?, ?";
		}

		sql = "INSERT INTO agendamento (" + campos + ") VALUES (" + valores + ")";

		dataSql = new java.sql.Date(movimentacao.getDataHoraEfetivacao().getTime());
		vencimentoSql = new java.sql.Date(movimentacao.getVencimento().getTime());
		
		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setDouble(1, movimentacao.getValor());
		stmt.setInt(2, movimentacao.getCodigoOrigem());
		stmt.setString(3, movimentacao.getTipoMovimentacao());
		stmt.setString(4, movimentacao.getDescricao());
		stmt.setDate(5, dataSql);
		stmt.setDate(6, vencimentoSql);
		if(movimentacao.getCodigoDestino() != null) {
			stmt.setInt(7, movimentacao.getCodigoDestino());
			stmt.setInt(8, movimentacao.getCodigoFavorecido());	
		}
		stmt.executeUpdate();
		conn.close();
 	}

	public static Double getSaldo(Integer codigoAgenciaConta) throws SQLException {

		Double retorno = 0.0;
		Connection conn = ConnectionFactory.getConnection();
		String sql = "SELECT SUM(valor) saldo FROM movimentacao WHERE codigo_origem = ?";

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setInt(1, codigoAgenciaConta);

		ResultSet rs = stmt.executeQuery();

		if(rs.next()){
			retorno = rs.getDouble("saldo");
		}

		stmt.close();
		rs.close();
		conn.close();
		return retorno;
	}
	
	public static List<Movimentacao> getUltimosComprovantesDao(Integer codigoAgenciaConta) throws SQLException {

		List<Movimentacao> retorno = new ArrayList<Movimentacao>();	
		Connection conn = ConnectionFactory.getConnection();

		String sql = "SELECT codigo, valor, data_hora, tipo_movimentacao, descricao " +
				"FROM movimentacao WHERE codigo_origem = ? AND tipo_movimentacao = 'PAGAMENTO' " +
				"ORDER BY data_hora DESC LIMIT 10";

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setInt(1, codigoAgenciaConta);

		ResultSet rs = stmt.executeQuery();

		while(rs.next()){
			Movimentacao mov = new Movimentacao();
			mov.setCodigo(rs.getInt("codigo"));
			mov.setValor(rs.getDouble("valor"));
			mov.setDataHora(rs.getDate("data_hora"));
			mov.setTipoMovimentacao(rs.getString("tipo_movimentacao"));
			mov.setDescricao(rs.getString("descricao"));
			retorno.add(mov);
		}

		stmt.close();
		rs.close();
		conn.close();
		return retorno;
	}
	
	public static List<Movimentacao> getComprovantesDao(Integer codigoAgenciaConta) throws SQLException {

		List<Movimentacao> retorno = new ArrayList<Movimentacao>();	
		Connection conn = ConnectionFactory.getConnection();

		String sql = "SELECT codigo, valor, data_hora, tipo_movimentacao, descricao " +
				"FROM movimentacao WHERE codigo_origem = ? AND valor < 0 " +
				"ORDER BY data_hora DESC";

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setInt(1, codigoAgenciaConta);

		ResultSet rs = stmt.executeQuery();

		while(rs.next()){
			Movimentacao mov = new Movimentacao();
			mov.setCodigo(rs.getInt("codigo"));
			mov.setValor(rs.getDouble("valor"));
			mov.setDataHora(rs.getDate("data_hora"));
			mov.setTipoMovimentacao(rs.getString("tipo_movimentacao"));
			mov.setDescricao(rs.getString("descricao"));
			retorno.add(mov);
		}

		stmt.close();
		rs.close();
		conn.close();
		return retorno;
	}

	public static Movimentacao getMovimentacaoDao(Integer codigoMovimentacao) throws SQLException {

		Connection conn = ConnectionFactory.getConnection();
		
		String sql = "SELECT valor, data_hora, tipo_movimentacao, descricao, vencimento, " +
				"codigo_destino, codigo_favorecido " +
				"FROM movimentacao WHERE codigo = ? ";

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setInt(1, codigoMovimentacao);

		ResultSet rs = stmt.executeQuery();
		Movimentacao mov = new Movimentacao();
		
		if(rs.next()){
			mov.setValor(rs.getDouble("valor"));
			mov.setDataHora(rs.getDate("data_hora"));
			mov.setTipoMovimentacao(rs.getString("tipo_movimentacao"));
			mov.setDescricao(rs.getString("descricao"));
			mov.setVencimento(rs.getDate("vencimento"));
			mov.setCodigoFavorecido(rs.getInt("codigo_favorecido"));
			mov.setCodigoDestino(rs.getInt("codigo_destino"));
		}

		stmt.close();
		rs.close();
		conn.close();
		return mov;
	}
	
	public static List<Movimentacao> getUltimosMovimentosDao(Integer codigoAgenciaConta) throws SQLException {

		List<Movimentacao> retorno = new ArrayList<Movimentacao>();	
		Connection conn = ConnectionFactory.getConnection();
		
		String sql = "SELECT valor, data_hora, tipo_movimentacao, descricao " +
				"FROM movimentacao WHERE codigo_origem = ? AND data_hora >= now() - interval '5 day' " +
				"ORDER BY data_hora";

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setInt(1, codigoAgenciaConta);

		ResultSet rs = stmt.executeQuery();

		while(rs.next()){
			Movimentacao mov = new Movimentacao();
			mov.setValor(rs.getDouble("valor"));
			mov.setDataHora(rs.getDate("data_hora"));
			mov.setTipoMovimentacao(rs.getString("tipo_movimentacao"));
			mov.setDescricao(rs.getString("descricao"));
			retorno.add(mov);
		}

		stmt.close();
		rs.close();
		conn.close();
		return retorno;
	}
	
	public static List<Movimentacao> getExtrato(Integer codigoAgenciaConta, Date de, Date ate) throws SQLException {
		Integer umDia = 86399999;
		java.sql.Date data_de = new java.sql.Date(de.getTime());
		java.sql.Date data_ate = new java.sql.Date(ate.getTime() + umDia);
		
		List<Movimentacao> retorno = new ArrayList<Movimentacao>();	
		Connection conn = ConnectionFactory.getConnection();

		String sql = "SELECT valor, data_hora, tipo_movimentacao, descricao, tipo_movimentacao " +
				"FROM movimentacao WHERE codigo_origem = ? AND data_hora >= ? AND data_hora <= ?" +
				"ORDER BY data_hora";

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setInt(1, codigoAgenciaConta);
		stmt.setDate(2, data_de);
		stmt.setDate(3, data_ate);

		ResultSet rs = stmt.executeQuery();

		while(rs.next()){
			Movimentacao mov = new Movimentacao();
			mov.setValor(rs.getDouble("valor"));
			mov.setDataHora(rs.getDate("data_hora"));
			mov.setTipoMovimentacao(rs.getString("tipo_movimentacao"));
			mov.setDescricao(rs.getString("descricao"));
			retorno.add(mov);
		}
		
		sql = "SELECT SUM(valor) saldo FROM movimentacao WHERE codigo_origem = ? AND data_hora <= ?";

		PreparedStatement stmtSaldo = conn.prepareStatement(sql);
		stmtSaldo.setInt(1, codigoAgenciaConta);
		stmtSaldo.setDate(2, data_ate);

		ResultSet rsSaldo = stmtSaldo.executeQuery();
		
		if(rsSaldo.next()){
			Movimentacao mov = new Movimentacao();
			mov.setValor(rsSaldo.getDouble("saldo"));
			mov.setDataHora(ate);
			mov.setTipoMovimentacao("*");
			mov.setDescricao("SALDO NESTA DATA");
			retorno.add(mov);
		}

		stmt.close();
		rs.close();

		stmtSaldo.close();
		rsSaldo.close();

		conn.close();
		return retorno;
	}
	
	public static List<Movimentacao> getAgendamentos(Integer codigoAgenciaConta) throws SQLException {
		Double somatoriaAgendamentos = 0.0;
		List<Movimentacao> retorno = new ArrayList<Movimentacao>();	
		Connection conn = ConnectionFactory.getConnection();

		String sql = "SELECT valor, data_hora_efetivacao, tipo_movimentacao, descricao " +
				"FROM agendamento WHERE codigo_origem = ? AND data_hora_efetivacao >= now() " +
				"ORDER BY data_hora_efetivacao ";

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setInt(1, codigoAgenciaConta);

		ResultSet rs = stmt.executeQuery();

		while(rs.next()){
			somatoriaAgendamentos += rs.getDouble("valor");

			Movimentacao mov = new Movimentacao();
			mov.setValor(rs.getDouble("valor"));
			mov.setDataHora(rs.getDate("data_hora_efetivacao"));
			mov.setTipoMovimentacao(rs.getString("tipo_movimentacao"));
			mov.setDescricao(rs.getString("descricao"));
			retorno.add(mov);
		}
		
		Movimentacao mov = new Movimentacao();
		mov.setValor(somatoriaAgendamentos);
		mov.setTipoMovimentacao("*");
		mov.setDescricao("VALOR TOTAL AGENDADO");
		retorno.add(mov);

		sql = "SELECT SUM(valor) saldo FROM movimentacao WHERE codigo_origem = ?";

		PreparedStatement stmtSaldo = conn.prepareStatement(sql);
		stmtSaldo.setInt(1, codigoAgenciaConta);

		ResultSet rsSaldo = stmtSaldo.executeQuery();
		
		if(rsSaldo.next()){
			Movimentacao mov2 = new Movimentacao();
			mov2.setValor(rsSaldo.getDouble("saldo") + somatoriaAgendamentos);
			mov2.setTipoMovimentacao("*");
			mov2.setDescricao("SALDO PREVISTO");
			retorno.add(mov2);
		}

		stmt.close();
		rs.close();
		
		stmtSaldo.close();
		rsSaldo.close();

		conn.close();
		return retorno;
	}
}